package cn.javaxxw.zxing.spring.boot.utils;

import net.coobird.thumbnailator.Thumbnails;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * ImageUtils
 * @author 		： <a href="https://github.com/hiwepy">wandl</a>
 */
public class ImageUtils {

    public static BufferedImage buffered(Image source) throws IOException {
        if(source instanceof BufferedImage) {
            return (BufferedImage) source;
        }
        BufferedImage redraw = new BufferedImage(source.getWidth(null), source.getWidth(null), BufferedImage.TYPE_INT_RGB);
        Graphics g = redraw.getGraphics();
        g.drawImage(source, 0, 0, null);
        g.dispose();
        return redraw;
    }

    public static BufferedImage scale(Image source, int height, int width) throws IOException {
        return scale(buffered(source), height, width);
    }

    public static BufferedImage scale(BufferedImage source, int height, int width) throws IOException {

        /**
         double ratioW = (new Integer(width)).doubleValue() / source.getWidth();
         double ratioH = (new Integer(height)).doubleValue() / source.getHeight();
         AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratioW, ratioH), null);
         Image scaleImage = op.filter(source, null);
         */

        // 图片尺寸缩放
        Image scaleImage = Thumbnails.of(source).size(width, height).asBufferedImage();
        // 自动补白
        return filler(scaleImage, height, width);
    }

    public static BufferedImage filler(BufferedImage source, int height, int width) throws IOException {
        return filler((Image) source, height, width);
    }

    public static BufferedImage filler(Image source, int height, int width) throws IOException {
        // 补白
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphic = image.createGraphics();
        graphic.setColor(Color.white);
        graphic.fillRect(0, 0, width, height);
        if (width == source.getWidth(null)) {
            graphic.drawImage(source, 0, (height - source.getHeight(null)) / 2, source.getWidth(null),
                    source.getHeight(null), Color.white, null);
        } else {
            graphic.drawImage(source, (width - source.getWidth(null)) / 2, 0, source.getWidth(null),
                    source.getHeight(null), Color.white, null);
        }
        graphic.dispose();
        // 返回补白后的图片对象
        return image;
    }

    /**
     * 控制字符两端对齐
     * <p>如果字符太多而宽度太小，会导致字符叠加</p>
     * @param g {@link Graphics}
     * @param code 字符串
     * @param x 起始x坐标
     * @param y 起始y坐标
     * @param maxWidth 最大宽度
     */
    public static void drawString(Graphics g, String code, int x, int y, int maxWidth) {
        String[] split = code.split("");
        int len = split.length;
        int step = new Long(Math.round(maxWidth / len)).intValue();
        int tmpX = x;
        for (int i = 0; i < len; i++) {
            g.drawString(split[i], tmpX, y);
            tmpX = tmpX + step;
        }
    }


    /**
     * {@link Image} 转 {@link BufferedImage}
     * @param img {@link Image}
     * @return {@link BufferedImage}
     */
    public static BufferedImage toBufferedImage(Image img) {
        if (img instanceof BufferedImage) {
            return (BufferedImage) img;
        }
        return copyImage(img, BufferedImage.TYPE_INT_RGB);
    }

    /**
     * 将已有{@link Image}复制新的一份出来
     * @param img {@link Image}
     * @param imageType {@link BufferedImage}中的常量，图像类型，例如黑白等
     * @return {@link BufferedImage}
     * @see BufferedImage#TYPE_INT_RGB
     * @see BufferedImage#TYPE_INT_ARGB
     * @see BufferedImage#TYPE_INT_ARGB_PRE
     * @see BufferedImage#TYPE_INT_BGR
     * @see BufferedImage#TYPE_3BYTE_BGR
     * @see BufferedImage#TYPE_4BYTE_ABGR
     * @see BufferedImage#TYPE_4BYTE_ABGR_PRE
     * @see BufferedImage#TYPE_BYTE_GRAY
     * @see BufferedImage#TYPE_USHORT_GRAY
     * @see BufferedImage#TYPE_BYTE_BINARY
     * @see BufferedImage#TYPE_BYTE_INDEXED
     * @see BufferedImage#TYPE_USHORT_565_RGB
     * @see BufferedImage#TYPE_USHORT_555_RGB
     */
    public static BufferedImage copyImage(Image img, int imageType) {
        final BufferedImage buffer = new BufferedImage(img.getWidth(null),
                img.getHeight(null), imageType);
        final Graphics2D g = buffer.createGraphics();
        g.drawImage(img, 0, 0, null);
        g.dispose();
        return buffer;
    }

    /**
     * 从图片流中读取图片
     * @param in 图片文件流
     * @return 图片
     * @throws IOException IO异常
     */
    public static BufferedImage read(InputStream in) throws IOException {
        if (in instanceof ImageInputStream) {
            return ImageIO.read(in);
        }
        return ImageIO.read(getImageInputStream(in));
    }

    /**
     * 获取{@link ImageInputStream}
     * @param in {@link InputStream}
     * @return {@link ImageInputStream}
     * @throws IOException IO异常
     */
    private static ImageInputStream getImageInputStream(InputStream in) throws IOException {
        return ImageIO.createImageInputStream(in);
    }

    /**
     * 从文件中读取图片
     * @param imageFile 图片文件
     * @return 图片
     * @throws IOException IO异常
     */
    public static BufferedImage read(File imageFile) throws IOException {
        return ImageIO.read(imageFile);
    }
}